package net.esj.auth.inst.struts2;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.annotation.PostConstruct;

import net.esj.auth.Constants;
import net.esj.auth.inst.struts2.AdminAction.CoreSimpleAdmin;
import net.esj.auth.manager.AuthManager;
import net.esj.auth.pojo.CoreAdmin;
import net.esj.auth.pojo.CoreAdmin.ADMIN_STATE;
import net.esj.auth.pojo.CoreAuthFunc;
import net.esj.auth.pojo.CoreAuthGroup;
import net.esj.basic.core.engine.support.MelonSupporter;
import net.esj.basic.core.engine.tools.crypt.inst.PwdEncryptor;
import net.esj.basic.core.view.action.SearcherActionAware;
import net.esj.basic.core.view.support.vojo.BaseVojo;
import net.esj.basic.core.view.support.vojo.TransObject;
import net.esj.basic.exception.MelonException;
import net.esj.basic.exception.MelonRuntimeException;
import net.esj.basic.service.provider.UserRuleProvider;
import net.esj.basic.utils.DateUtils;
import net.esj.basic.utils.Validators;
import net.esj.basic.utils.view.BaseJsonMessage.MessageLevel;
import net.esj.basic.utils.writer.WriterCode;

public class AdminAction extends AbstractAuthAction<CoreAdmin, CoreSimpleAdmin> implements Constants,SearcherActionAware {
	
	private PwdEncryptor pwdEncryptor;
	
	private List<CoreAuthGroup> groups;
	
	private AuthManager authManager;
	
	private String model;

	private int state;
	
	private String name;
	
	

	@Override
	public String list() {
		model = UserRuleProvider.getUserRule(CoreAdmin.class).getAuthModel();
		return super.list();
	}

	public String grant(){
		//groups = defaultService.findAll(CoreAuthGroup.class);
		CoreAdmin admin = getSessionUser(CoreAdmin.class);
		List<String> list = new ArrayList<String>();
		list = authManager.getChildAdmin(admin.getId(), list);
		list.add(admin.getId());
		groups = authManager.listGroupByAdmin(list);
		return SUCCESS;
	}

	@Override
	protected void doQueryPage() {
		CoreAdmin admin = getSessionUser(CoreAdmin.class);
		if(!Validators.isEmpty(admin)){
			pagination = authManager.pageAdmin(pagination,admin);
			List<CoreSimpleAdmin> list = new ArrayList<AdminAction.CoreSimpleAdmin>();
			for(Object o : pagination.getRows()){
				list.add((CoreSimpleAdmin) defaultService.translate(o, CoreSimpleAdmin.class));
			}
			pagination.setRows(list);
		}
	}

	@Override
	public void doAdd() throws MelonException {
			if(authManager.checkUsernameExist(entity.getName())){
				throw new MelonException("admin.name.exists");
			}
			CoreAdmin admin = getSessionUser(CoreAdmin.class);
			if(!Validators.isEmpty(admin)){
				entity.setCreatorId(admin.getId());
				entity.setCreatorName(admin.getName());
				entity.setPassword(pwdEncryptor.encrypt(entity.getPassword(), entity.getName()));
				entity.setGmtCreate(DateUtils.now());
				defaultService.save(entity,entityClass);
			}
	}

	@Override
	public void doUpdate() throws MelonException {
			CoreAdmin admin = defaultService.get(entity.getId(), CoreAdmin.class);
			admin.setAddress(entity.getAddress());
			admin.setPhone(entity.getPhone());
			admin.setSubName(entity.getSubName());
			admin.setState(entity.getState());
			if(!Validators.isEmpty(entity.getPassword()) && !pwdEncryptor.checksum(entity.getPassword(), admin.getName(), admin.getPassword())){
				admin.setPassword(pwdEncryptor.encrypt(entity.getPassword(), admin.getName()));
			}
			admin.setGmtModify(DateUtils.now());
			defaultService.update(admin);
	}

	//复制权限
	public void copyAuth(){
		CoreAdmin admin = authManager.getAdminWithName(name,id);
		if(admin==null){
			writeBaseJsonMessage(getText(SYSTEM_MESSAGE_TITLE,""), "复制权限账号不存在！", MessageLevel.INFO, "html");
		}else{
			writeBaseJsonMessage(getText(SYSTEM_MESSAGE_TITLE,""), addSuccMsg(), MessageLevel.INFO, "html");
		}
	}
	
	@Override
	public void doDelete() {
		/*StringBuilder sb = new StringBuilder();
		for (String str : deletes.split(";")) {
			CoreAdmin admin = defaultService.get(str, CoreAdmin.class);
			if(admin!=null){
				defaultService.delete(admin);
				//sb.append(admin.getName()).append(",");
			}
		}*/
		CoreAdmin admin = new CoreAdmin();
		admin.setId(deletes);
		authManager.deleteAdmin(admin);	
	}

	public void load()throws MelonRuntimeException {
		if (Validators.isEmpty(id)) {
			return;
		}
//		CoreAdmin admin = defaultService.getFull(id, entityClass, new String[]{"groups","functions"});//FIXME 这样列表里只有1个,我操.... 
		CoreAdmin admin =authManager.getAdminWithAuth(id);
		//CoreAdmin admin =defaultService.get(id, CoreAdmin.class);
		entity = (CoreSimpleAdmin) defaultService.translate(admin, voClass);
		entity.setPassword("");
		entity.setFuncsSet(admin.getFunctions());
		entity.setGrsSet(admin.getGroups());
		writeJson(entity,WriterCode.FORM);
	}

	public void doGrant(){
		CoreAdmin admin =  defaultService.get(entity.getId(),CoreAdmin.class);
		//admin.getFunctions().clear();
		//admin.getGroups().clear();
		Set<CoreAuthFunc> funcSet = new HashSet<CoreAuthFunc>();
		for(String func: entity.getFuncs()){
			if(!Validators.isEmpty(func)){
				CoreAuthFunc f = new CoreAuthFunc();
				f.setId(func);
				funcSet.add(f);
			}
		}
		authManager.grantFuncs(admin, new ArrayList<CoreAuthFunc>(funcSet));
		//admin.setFunctions(funcSet);
		
		Set<CoreAuthGroup> groupSet = new HashSet<CoreAuthGroup>();
		for(String gr:entity.getGrs()){
			if(!Validators.isEmpty(gr)){
				CoreAuthGroup group = new CoreAuthGroup();
				group.setId(gr);
				groupSet.add(group);
			}
		}
		authManager.grantGroups(admin, new ArrayList<CoreAuthGroup>(groupSet));
		//admin.setGroups(groupSet);
		
		//defaultService.update(admin);
		writeBaseJsonMessage("", getText(ACTION_SUCCESS), MessageLevel.INFO, "html");
	}
	
	public void state(){
		CoreAdmin admin = defaultService.get(id, CoreAdmin.class);
		if(admin!=null){
			admin.setState(state);
			defaultService.update(admin);
		}
		writeBaseJsonMessage("", getText(ACTION_SUCCESS), MessageLevel.INFO, "html");
	}
	
	public CoreSimpleAdmin getEntity() {
		return entity;
	}

	public void setEntity(CoreSimpleAdmin entity) {
		this.entity = entity;
	}
	
	@PostConstruct
	private void initPost(){
		if(pwdEncryptor==null){
			pwdEncryptor = MelonSupporter.getPwdEncryptor();
		}
	}
	
	public static class CoreSimpleAdmin implements BaseVojo<String>,TransObject{
		
		private String id;
		private String name;
		private String subName;
		private String password;
		private Date gmtCreate;
		private Date gmtModify;
		private Date lastLoginTime;
		private String lastLoginIp;
		private int state;
		private int is_delete;
		private String phone;
		private String address;
		private String creatorId;
		private String creatorName;
		
		

		private String[] grs;
		private String[] funcs;
		
		public String getPhone() {
			return phone;
		}

		public void setPhone(String phone) {
			this.phone = phone;
		}

		public String getAddress() {
			return address;
		}

		public void setAddress(String address) {
			this.address = address;
		}
		public int getIs_delete() {
			return is_delete;
		}

		public void setIs_delete(int is_delete) {
			this.is_delete = is_delete;
		}
		public int getState() {
			return state;
		}

		public void setState(int state) {
			this.state = state;
		}

		public String getName() {
			return name;
		}

		public void setName(String name) {
			this.name = name;
		}

		public Date getGmtCreate() {
			return gmtCreate;
		}

		public void setGmtCreate(Date gmtCreate) {
			this.gmtCreate = gmtCreate;
		}

		public Date getGmtModify() {
			return gmtModify;
		}

		public void setGmtModify(Date gmtModify) {
			this.gmtModify = gmtModify;
		}

		public Date getLastLoginTime() {
			return lastLoginTime;
		}

		public void setLastLoginTime(Date lastLoginTime) {
			this.lastLoginTime = lastLoginTime;
		}

		public String getLastLoginIp() {
			return lastLoginIp;
		}

		public void setLastLoginIp(String lastLoginIp) {
			this.lastLoginIp = lastLoginIp;
		}

		@Override
		public String getId() {
			return id;
		}

		@Override
		public void setId(String id) {
			this.id = id;
		}

		public String getSubName() {
			return subName;
		}

		public void setSubName(String subName) {
			this.subName = subName;
		}

		public String getPassword() {
			return password;
		}

		public void setPassword(String password) {
			this.password = password;
		}

		public String[] getGrs() {
			return grs;
		}

		public void setGrs(String grs) {
			this.grs = grs.split(";");
		}
		
		public void setGrsSet(Set<CoreAuthGroup> grs) {
			this.grs = new String[grs.size()];
			int i=0;
			for(CoreAuthGroup g : grs){
				this.grs[i] = g.getId();
				i++;
			}
		}

		public String[] getFuncs() {
			return funcs;
		}

		public void setFuncs(String funcs) {
			this.funcs = funcs.split(";");
		}
		public void setFuncsSet(Set<CoreAuthFunc> funcs) {
			this.funcs = new String[funcs.size()];
			int i=0;
			for(CoreAuthFunc f : funcs){
				this.funcs[i] = f.getId();
				i++;
			}
		}
		public String getCreatorId() {
			return creatorId;
		}

		public void setCreatorId(String creatorId) {
			this.creatorId = creatorId;
		}
		public String getCreatorName() {
			return creatorName;
		}

		public void setCreatorName(String creatorName) {
			this.creatorName = creatorName;
		}
		
	}

	public void setPwdEncryptor(PwdEncryptor pwdEncryptor) {
		this.pwdEncryptor = pwdEncryptor;
	}
	
	public CoreAdmin getMine(){
		return getSessionUser(CoreAdmin.class);
	}

	public List<CoreAuthGroup> getGroups() {
		return groups;
	}

	public void setAuthManager(AuthManager authManager) {
		this.authManager = authManager;
	}

	public String getModel() {
		return model;
	}

	public void setModel(String model) {
		this.model = model;
	}

	public int getState() {
		return state;
	}

	public void setState(int state) {
		this.state = state;
	}

	public ADMIN_STATE[] getStates(){
		return ADMIN_STATE.values();
	}
	

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	

}
